package com.quanyou.base.framework.dao;

import com.quanyou.base.framework.dao.domain.BaseDomain;
import com.quanyou.base.framework.dao.model.BaseModel;
import com.quanyou.base.framework.dao.model.PageParams;
import com.quanyou.base.framework.dao.model.PageResults;
import tk.mybatis.mapper.entity.Example;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

/**
 * 基础服务接口
 * Created by forever on 6/18/15.
 */
@SuppressWarnings("unchecked")
public interface AbstractDao<E extends BaseDomain<PK>, PK extends Serializable, M extends BaseModel<E>> {

    /**
     * <p>保存实体对象 </p>
     *
     * @param entity 实体对象
     * @return 单主键
     */
    PK save(E entity);

    /**
     * <p>方法描述</p>
     * @param entityList 实体对象列表
     * @return 保存成功数目
     */
    int save(Collection<E> entityList);

    /**
     * 根据主键更新
     *
     * @param object 更新值
     * @return 更新记录数
     */
    @Deprecated
    int update(E object);

    /**
     * <p> 更新实体，空值会用Null覆盖数据库中得值 </p>
     * @param object 实体
     */
    int updateByPrimaryKey(E object);

    /**
     * 更新实体，以主键确定记录，只更新非空的值，需要设空得操作请使用updateByPrimaryKey
     * @param e 实体
     * @return 更新记录数
     */
    int updateSelectiveByPrimaryKey(E e);

    void delete(PK id);

    void delete(List<E> objectlist);

    E get(PK id);

    //TODO 若数据库内有多条符合条件的数据，会抛出异常，需外部处理
    E get(E domain);

    E getByExample(Example example);

    //TODO 增加动态指定所需列的方法，提高性能
    /**
     * <p> 分页查询实体对象（通过Entity） </p>
     * @param pp
     * @return
     * @return PageResults<E>
     */
    PageResults<E> queryPageResults(PageParams<E> pp);

    PageResults<E> queryPageResults(PageParams<E> pp, Example example);

    /**
     *
     * @param e
     * @return
     */
    List<E> findByPropertys(E e);

    //TODO 注释补全
    int selectCount(E e);

    int selectCountByExample(Example example);


    boolean exists(E e);

    /**
     * 根据Example查询条件查询
     * @param example 查询条件
     * @return 记录列表
     */
    List<E> findByExample(Example example);


    int updateByExampleSelective(E record, Example example);

    /**
     * 用提供的记录中的值，更新Example查询条件匹配的记录，包括空值
     * @param record 更新值
     * @param example 查询条件
     * @return 更新的记录数
     */
    int updateByExample(E record, Example example);

    /**
     * 列出全部记录，适合记录较少的表
     * @return 全部记录集合
     */
    List<E> listAll();

}
